package ajaxjs.data.service;

import java.sql.Connection;

import javax.script.ScriptException;
import javax.servlet.http.HttpServletRequest;

import ajaxjs.Constant;
import ajaxjs.config.Application;
import ajaxjs.sql.DAO;

public abstract class BaseService implements Service{
	public Connection jdbcConn = null;
	
	public Connection getJdbcConn(){
		return this.jdbcConn;
	}
	public HttpServletRequest request = null;
	
	public void setObjs(HttpServletRequest request, Connection jdbcConn){
		this.request = request;
		this.jdbcConn = jdbcConn;
	}
	public Object call(String methodName, Object...arg){
		try {
			return Application.jsRuntime.call(methodName, arg);
		} catch (ScriptException e) {
			e.printStackTrace();
			request.setAttribute("errMsg", e.getMessage());
			return null;
		}
	}
	
	public String findList(String queryStr){
		String returnValue = null;
		
		Object sqls = null;
		sqls = call("bf_service_findList", this, request, queryStr);

		String sql = getSql(sqls);
		
		String[] sqls_arr = sql.split("###");
		String countSql = sqls_arr[0], resultSql= sqls_arr[1];
		
		DAO dao = new DAO(jdbcConn);
		final Integer _total = (Integer)dao.query(countSql, true);
		
		if(_total == null){
			returnValue = queryZero();
			System.out.println("请求返回数据-------->没有数据哦~");
		}else{
			// jsonArr 是 js 的 Array
			Object jsonArr = dao.queryAsJSON(resultSql, Application.jsRuntime); 
			
			System.out.println("数据库查询 findList() " + Constant.printObject_or_status + "成功！");
			
			// formatter
			call("formatter", getPojo(), jsonArr);
			returnValue = call("list_output", _total, jsonArr).toString();
		}
		
		request.setAttribute("isRawOutput", true);
		request.setAttribute("msg", returnValue);
		
		System.out.println(Constant.ConsoleDiver);
		System.out.println("请求返回数据 " + Constant.printObject_or_status + "成功！");
		
		return returnValue;
	}
	
	public String findList(){
		return findList(null);
	}
	
	public String findById(int id){
		String returnValue = null, sql = null;
		DAO dao = new DAO(jdbcConn);
		Object jsonArr =  null;
		
		sql = getSql(call("bf_service_findById", this, id));
		jsonArr = dao.queryAsJSON(sql, Application.jsRuntime);
		
		if(jsonArr == null){
			returnValue = queryZero();
		}else{
			call("setValue", getPojo(), jsonArr);
			call("formatter", getPojo(), jsonArr);
			returnValue = (String)call("list_output", jsonArr);
			 
		}
		request.setAttribute("isRawOutput", true);
		request.setAttribute("msg", returnValue);
		return returnValue;
	}
	
	/**
	 * 统一的处理 SQL 方法
	 * @return
	 */
	private static String getSql(Object sql){
		if(sql == null){
			throw new NullPointerException("没有返回 SQL");
		}else{			
			ajaxjs.Util.log("根据业务规则，生成 SQL 语句成功！", BaseService.class);
			// System.out.println(sql.toString());
			return sql.toString();
		}
	}
	
	private static String queryZero(){
		return Application.jsRuntime.parseObj(new Object() {  
			@SuppressWarnings("unused")
			public int total = 0;   
			@SuppressWarnings("unused")
			public String msg = ajaxjs.Constant.sql_query_zero;
		});
	}
	
	/**
	 * 
	 * @param where
	 * @return
	 */
	public String find(String where){
		String returnValue = null;
		String sql = getSql(call("bf_service_find", this, where));
		
		if(sql != null){
			DAO dao = new DAO(jdbcConn);
			Object json = dao.queryAsJSON(sql, Application.jsRuntime);
			
			 call("setValue", getPojo(), json); // 如果是单数这一步才有意义
			 call("formatter", getPojo(), json);
			returnValue = (String) call("list_output", json);
			 
		}
		
		return returnValue;
	}
	
	public int create(){
		String sql = getSql(call("bf_service_create", this, request));
		int newId = new DAO(jdbcConn).executeUpdate(sql);
		
		if(newId != 0){
			request.setAttribute("msg", printOk("创建记录成功！", newId));
		}else{
			request.setAttribute("errMsg", showException("创建记录失败！"));
		}
		
		return newId;
	}
	public boolean update(int id){
		return update(id, true);
	}
	public boolean update(int id, boolean isPut){
		String sql = null;
		if(isPut)
			sql = (String)call("bf_service_update", this, request, id, true);
		else 
			sql = (String)call("bf_service_update", this, request, id, false);
		
		int effRow = new DAO(jdbcConn).executeUpdate(sql);
		if(effRow > 0) request.setAttribute("msg", printOk("更新记录" + id +"成功！"));
		else request.setAttribute("errMsg", showException("更新记录" + id +"失败！"));
		
		return effRow > 0;
	}
	
	public boolean delete(int id){
		String sql = "DELETE FROM " + this.getTableName() + " WHERE id = " + id;

		DAO dao = new DAO(jdbcConn);
		
		if(dao.executeUpdate(sql) != 0){// 0 表示找不到 记录
			request.setAttribute("msg", "删除记录" + id +"成功！");
			return true;
		}else{
			request.setAttribute("errMsg", "删除记录" + id +"失败！");
			return false;
		}
	}
	
	public String printOk(final String _msg){
		return Application.jsRuntime.parseObj(new Object() {  
			@SuppressWarnings("unused")
			public boolean isOk = true;   
			@SuppressWarnings("unused")
			public String msg = _msg;
		});
	}
	
	/**
	 * for create
	 * @param _msg
	 * @return
	 */
	private String printOk(final String _msg, final int _newId){
		return Application.jsRuntime.parseObj(new Object() {  
			@SuppressWarnings("unused")
			public boolean isOk = true;   
			@SuppressWarnings("unused")
			public String msg = _msg;
			@SuppressWarnings("unused")
			public int newId = _newId;
		});
	}
	
	public String showException(final Exception e, String msg){
//		ajaxjs.Util.catchException(e, msg); // 报告异常
		
		return Application.jsRuntime.parseObj(new Object() {  
			@SuppressWarnings("unused")
			public boolean isOk = false;   
			@SuppressWarnings("unused")
			public String msg = e.getMessage();
		});
	}
	public String showException(String msg){
		return showException(new Exception(msg), msg);
	}
	
	abstract public String getTableName();
	public String hot(){
		return findList(getTableName() + ".isHot = 1 ");
	}
	public String resetHot(){
		MiscService ms = new MiscService(jdbcConn, request);
		
		try {
			return printOk(ms.resetHot(getTableName()));
		} catch (Exception e) {
			e.printStackTrace();
			return showException(e.getMessage());
		}
	}
}
